package org.afs.gescol.gwt.client.controller;

import java.util.HashMap;
import java.util.Map;

import org.afs.gescol.component.edt.gwt.client.factory.EdtComponentClientFactory;
import org.afs.gescol.component.edt.gwt.client.presenter.EmploiDuTempsPresenter;
import org.afs.gescol.component.edt.gwt.shared.ConstantesKeysModel;
import org.afs.gescol.gwt.client.bundle.GescolResources;
import org.afs.gescol.gwt.client.event.EditPersonneEvent;
import org.afs.gescol.gwt.client.factory.AppClientFactory;
import org.afs.gescol.gwt.client.i18n.AppMessages;
import org.afs.gescol.gwt.client.presenter.ConfigurationsPresenter;
import org.afs.gescol.gwt.client.presenter.ElevePresenter;
import org.afs.gescol.gwt.client.presenter.HomePresenter;
import org.afs.gescol.gwt.client.service.GetServicesGwt;
import org.afs.gescol.gwt.client.util.ConstantesKeys;
import org.afs.gescol.gwt.shared.GlobalConstantesModel;
import org.scub.foundation.framework.gwt.module.client.factory.ClientFactory;
import org.scub.foundation.framework.gwt.module.client.mvp.controller.Controller;
import org.scub.foundation.framework.gwt.module.client.mvp.management.alert.AlertPresenter;
import org.scub.foundation.framework.gwt.module.client.mvp.management.confirm.ConfirmPresenter;
import org.scub.foundation.framework.gwt.module.client.mvp.management.error.ErrorPresenter;
import org.scub.foundation.framework.gwt.module.client.mvp.management.loading.LoadingPresenter;
import org.scub.foundation.framework.gwt.module.client.mvp.view.View;
import org.scub.foundation.framework.gwt.module.client.util.TokenUtil;
import org.scub.foundation.framework.gwt.module.client.util.composants.suggestbox.SuggestListBoxSuggestEvent;
import org.scub.foundation.framework.gwt.module.client.util.composants.suggestbox.SuggestListBoxSuggestEventHandler;
import org.scub.foundation.framework.gwt.module.client.util.composants.tabpanel.event.CloseTabEvent;
import org.scub.foundation.framework.gwt.module.client.util.composants.tabpanel.event.CloseTabHandler;
import org.scub.foundation.framework.gwt.module.client.util.composants.tabpanel.event.SelectTabEvent;
import org.scub.foundation.framework.gwt.module.client.util.composants.tabpanel.event.SelectTabHandler;
import org.scub.foundation.framework.gwt.module.shared.IdLabelModel;

import com.github.gwtbootstrap.client.ui.constants.IconType;
import com.google.gwt.dom.client.StyleInjector;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HasWidgets;

/**
 * Application controler.
 * @autor Kobla GBENYO (kobla.gbenyo@gmail.com)
 */
public class AppController extends Controller implements ValueChangeHandler<String> {

    private AppLayout layout = AppClientFactory.getLayout();

    private HomePresenter homePresenter = AppClientFactory.getHomePresenter();

    private EmploiDuTempsPresenter emploiDuTempsPresenter = EdtComponentClientFactory.getEdtComponent();

    private ConfigurationsPresenter configurationsPresenter = AppClientFactory.getConfigurationsPresenter();

    private LoadingPresenter loadingPresenter = ClientFactory.getLoadingPresenter();

    private ErrorPresenter errorPresenter = ClientFactory.getErrorPresenter();

    private ConfirmPresenter confirmPresenter = ClientFactory.getConfirmPresenter();

    private AlertPresenter alertPresenter = ClientFactory.getAlertPresenter();

    private AppMessages messages = AppClientFactory.getMessages();

    private GescolResources resources = AppClientFactory.getResources();

    private GlobalConstantesModel constantesModel;

    private Map<String, ElevePresenter> mapElevePresenter = new HashMap<String, ElevePresenter>();

    @Override
    public void onDetach() {
    }

    @Override
    public View getLayout() {
        return layout;
    }

    @Override
    public void initLayout() {
        layout.init();
        // add config tab by default
        layout.getTabPanelHandlers().addTab(getDefaultToken(), messages.searchTab(), false, IconType.SEARCH);
        layout.getTabPanelHandlers().addTab(AppClientFactory.EDT_TOKEN, messages.edtTab(), false, IconType.TAG);
        layout.getTabPanelHandlers().addTab(AppClientFactory.NOTE_TOKEN, messages.noteTab(), false, IconType.BOOK);
        layout.getTabPanelHandlers().addTab(AppClientFactory.STATS_TOKEN, messages.statsTab(), false, IconType.BAR_CHART);
        layout.getTabPanelHandlers().addTab(AppClientFactory.CONFIG_TOKEN, messages.configTab(), false, IconType.COGS);
        buildEdtComponent();
    }

    @Override
    public void onBind() {
        layout.getTabPanelHandlers().addSelectTabHandler(new SelectTabHandler() {
            @Override
            public void onTabSelected(SelectTabEvent event) {
                History.newItem(event.getToken());
            }
        });
        layout.getTabPanelHandlers().addCloseTabHandler(new CloseTabHandler() {
            @Override
            public void onTabClosed(CloseTabEvent event) {
                final String token = event.getToken();
                final String page = TokenUtil.getPage(token);
                if (page.equals(EditPersonneEvent.PAGE)) {
                    final Long typePersonne = Long.valueOf(TokenUtil.getValue(token, EditPersonneEvent.PARAM_TYPE_PERSON));
                    if (typePersonne.equals(HomePresenter.ID_TYPE_ELEVE)) {
                        mapElevePresenter.remove(token);
                    } else if (typePersonne.equals(HomePresenter.ID_TYPE_PERSONNEL)) {
                        
                    }
                }
            }
        });
        layout.getSlbCycleHandlers().addSuggestHandler(new SuggestListBoxSuggestEventHandler<IdLabelModel>() {
            @Override
            public void suggest(SuggestListBoxSuggestEvent<IdLabelModel> event) {
                GetServicesGwt.App.getInstance().getCycleByUser(constantesModel.getLoggedUser().getId(), event.getCallBack());
            }
        });
        layout.getSlbAnneeHandlers().addSuggestHandler(new SuggestListBoxSuggestEventHandler<IdLabelModel>() {
            @Override
            public void suggest(SuggestListBoxSuggestEvent<IdLabelModel> event) {
                GetServicesGwt.App.getInstance().getAnneeByName(event.getSuggest(), event.getCallBack());
            }
        });
        layout.getSlbPeriodeHandlers().addSuggestHandler(new SuggestListBoxSuggestEventHandler<IdLabelModel>() {
            @Override
            public void suggest(SuggestListBoxSuggestEvent<IdLabelModel> event) {
                GetServicesGwt.App.getInstance().getPeriodeByAnnee(constantesModel.getOpenedYear().getId(), event.getCallBack());
            }
        });
    }

    @Override
    public void onShow(HasWidgets.ForIsWidget container) {
        addChildPresenter(loadingPresenter);
        addChildPresenter(errorPresenter);
        addChildPresenter(confirmPresenter);
        addChildPresenter(alertPresenter);

        errorPresenter.showPresenter(null);
        loadingPresenter.showPresenter(null);
        confirmPresenter.showPresenter(null);
        alertPresenter.showPresenter(null);

        StyleInjector.inject(resources.css().getText());
        layout.getSlbCycleHandlers().setValue(constantesModel.getOpenedCycle());
        layout.getSlbAnneeHandlers().setValue(constantesModel.getOpenedYear());
        layout.getSlbPeriodeHandlers().setValue(constantesModel.getOpenedPeriod());
        super.onShow(container);
    }

    @Override
    public String getDefaultToken() {
        return AppClientFactory.SEARCH_TOKEN;
    }

    @Override
    public void onTokenChange(final String token) {
        final String page = TokenUtil.getPage(token);
        if (page.equals(AppClientFactory.SEARCH_TOKEN)) {
            if (!homePresenter.isInitialized()) {
                addChildPresenter(homePresenter);
                homePresenter.showPresenter(layout.getTabContent(token));
            }
        } else if (page.equals(AppClientFactory.EDT_TOKEN)) {
            if (!emploiDuTempsPresenter.isInitialized()) {
                addChildPresenter(emploiDuTempsPresenter);
                emploiDuTempsPresenter.showPresenter(layout.getTabContent(token));
                bindEdtComponent();
            }
        } else if (page.equals(AppClientFactory.NOTE_TOKEN)) {
//            if (!homePresenter.isInitialized()) {
//                addChildPresenter(homePresenter);
//                homePresenter.showPresenter(layout.getTabContent(token));
//            }
            Window.alert("NOTE=>Pas encore implémenter!");
        } else if (page.equals(AppClientFactory.CONFIG_TOKEN)) {
            if (!configurationsPresenter.isInitialized()) {
                addChildPresenter(configurationsPresenter);
                configurationsPresenter.showPresenter(layout.getTabContent(token));
            }
        } else if (page.equals(AppClientFactory.STATS_TOKEN)) {
//            if (!homePresenter.isInitialized()) {
//                addChildPresenter(homePresenter);
//                homePresenter.showPresenter(layout.getTabContent(token));
//            }
            Window.alert("STATS=>Pas encore implémenter!");
        } else if (page.equals(EditPersonneEvent.PAGE)) {
            final Long typePersonne = Long.valueOf(TokenUtil.getValue(token, EditPersonneEvent.PARAM_TYPE_PERSON));
            final Long id = Long.valueOf(TokenUtil.getValue(token, EditPersonneEvent.PARAM_ID_PERSON));
            if (typePersonne.equals(HomePresenter.ID_TYPE_ELEVE)) {
                ElevePresenter elevePresenter = mapElevePresenter.get(token);
                if (elevePresenter == null) {
                    elevePresenter = addChildPresenter(AppClientFactory.getElevePresenter());
                    final String nom = TokenUtil.getValue(token, EditPersonneEvent.PARAM_NOM_PERSON);
                    layout.getTabPanelHandlers().addTab(token, nom, true, IconType.EDIT);
                    mapElevePresenter.put(token, elevePresenter);
                    elevePresenter.showPresenter(layout.getTabContent(token));
                }
                final Map<String, IdLabelModel> constantes = new HashMap<String, IdLabelModel>();
                constantes.put(ConstantesKeys.OPENED_YEAR_KEY, constantesModel.getOpenedYear());
                constantes.put(ConstantesKeys.OPENED_PERIOD_KEY, constantesModel.getOpenedPeriod());
                constantes.put(ConstantesKeys.TYPE_PERE_KEY, constantesModel.getTypePere());
                constantes.put(ConstantesKeys.TYPE_MERE_KEY, constantesModel.getTypeMere());
                constantes.put(ConstantesKeys.TYPE_TUTEUR_KEY, constantesModel.getTypeTuteur());
                constantes.put(ConstantesKeys.DEVISE_KEY, constantesModel.getDevise());
                elevePresenter.setConstantes(constantes);
                elevePresenter.loadData(id);
            } else if (typePersonne.equals(HomePresenter.ID_TYPE_PERSONNEL)) {
                
            }
        }
        layout.getTabPanelHandlers().selectTab(token);
    }

    private void buildEdtComponent() {
        final Map<String, IdLabelModel> constantes = new HashMap<String, IdLabelModel>();
        constantes.put(ConstantesKeys.OPENED_YEAR_KEY, constantesModel.getOpenedYear());
        constantes.put(ConstantesKeys.OPENED_PERIOD_KEY, constantesModel.getOpenedPeriod());
        constantes.put(ConstantesKeys.DEFAULT_CLASS_KEY, constantesModel.getDefaultClass());
        final ConstantesKeysModel constantesKeys = new ConstantesKeysModel();
        constantesKeys.setDefaultClassKey(ConstantesKeys.DEFAULT_CLASS_KEY);
        constantesKeys.setOpenedPeriodKey(ConstantesKeys.OPENED_PERIOD_KEY);
        constantesKeys.setOpenedYearKey(ConstantesKeys.OPENED_YEAR_KEY);
        emploiDuTempsPresenter.setConstantes(constantes);
        emploiDuTempsPresenter.setConstantesKeys(constantesKeys);
    }

    private void bindEdtComponent() {
        emploiDuTempsPresenter.getClassSuggestHandler().addSuggestHandler(new SuggestListBoxSuggestEventHandler<IdLabelModel>() {
            @Override
            public void suggest(SuggestListBoxSuggestEvent<IdLabelModel> event) {
                GetServicesGwt.App.getInstance().getClassByName(event.getSuggest(), event.getCallBack());
            }
        });
        emploiDuTempsPresenter.getPrintClickHandlers().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                final String appelServlet = "servlet/pdfDocumentsServlet?" + GlobalConstantesModel.DOC_TYPE + "=" + GlobalConstantesModel.EDT_DOC;
                Window.open(appelServlet, "_blank", "resizable=yes,menubar=no,location=no");
            }
        });
    }

    /**
     * Set the value of constantesModel.
     * @param constantesModel the constantesModel to set
     */
    public void setConstantesModel(GlobalConstantesModel constantesModel) {
        this.constantesModel = constantesModel;
    }
}
